package com.ruoyi.system.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.PictureInfoMapper;
import com.ruoyi.system.domain.PictureInfo;
import com.ruoyi.system.service.IPictureInfoService;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.ShiroUtils;

/**
 * 图片信息Service业务层处理
 * 
 * @author ruoyi
 */
@Service
public class PictureInfoServiceImpl implements IPictureInfoService 
{
    @Autowired
    private PictureInfoMapper pictureInfoMapper;

    private static final String REDIS_KEY_NEXT_PICTURE = "next_picture:";

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 查询图片信息
     * 
     * @param id 图片信息主键
     * @return 图片信息
     */
    @Override
    public PictureInfo selectPictureInfoById(Long id)
    {
        return pictureInfoMapper.selectPictureInfoById(id);
    }

    /**
     * 查询图片信息列表
     * 
     * @param pictureInfo 图片信息
     * @return 图片信息集合
     */
    @Override
    public List<PictureInfo> selectPictureInfoList(PictureInfo pictureInfo)
    {
        return pictureInfoMapper.selectPictureInfoList(pictureInfo);
    }

    /**
     * 查询用户标注历史列表
     * 
     * @param pictureInfo 图片信息（包含用户ID查询条件）
     * @return 用户标注历史集合
     */
    @Override
    public List<PictureInfo> selectUserAnnotationHistory(PictureInfo pictureInfo)
    {
        // 确保只查询已标注的图片（right_foot不为空）
        return pictureInfoMapper.selectUserAnnotationHistory(pictureInfo);
    }
    
    /**
     * 获取前一张图片ID
     * 
     * @param pictureInfo 图片信息（包含当前图片ID和用户ID）
     * @return 前一张图片ID
     */
    @Override
    public Long selectPreviousPictureId(PictureInfo pictureInfo) {
        return pictureInfoMapper.selectPreviousPictureId(pictureInfo);
    }
    
    /**
     * 获取后一张图片ID
     * 
     * @param pictureInfo 图片信息（包含当前图片ID和用户ID）
     * @return 后一张图片ID
     */
    @Override
    public Long selectNextPictureId(PictureInfo pictureInfo) {
        return pictureInfoMapper.selectNextPictureId(pictureInfo);
    }

    /**
     * 获取下一张待标注的图片
     * 
     * @return 待标注的图片信息，如果没有则返回null
     */
    @Override
    public synchronized PictureInfo getNextUnannotatedPicture()
    {
        PictureInfo pictureInfo = null;
        Long picId = null;
        //先获取一张图片
        pictureInfo = pictureInfoMapper.selectNextUnannotatedPicture(picId);
        while(Objects.nonNull(pictureInfo)){
            //如果获取到图片记录，则根据图片id，从redis中查询缓存，看有没有人在标注该图片
            Boolean cachedNextPictureId = redisTemplate.hasKey(REDIS_KEY_NEXT_PICTURE + pictureInfo.getId());
            if(!cachedNextPictureId){
                // 如果缓存没有该图片的id，说明没有用户在标注，则当前用户占用该图片，3分钟
                redisTemplate.opsForValue().set(REDIS_KEY_NEXT_PICTURE + pictureInfo.getId(), pictureInfo.getId(), 5L, TimeUnit.MINUTES);
                return pictureInfo;
            }else{
                //如果缓存中有该图片ID， 说明有用户在标注该图片，则向后寻找下一张图片
                picId = pictureInfo.getId();
                pictureInfo = pictureInfoMapper.selectNextUnannotatedPicture(picId);
            }
        }
        return pictureInfo;
    }

    /**
     * 保存标注信息并获取下一张图片
     * 
     * @param pictureInfo 标注信息（包含id、rightFoot、leftFoot、leg）
     * @return 下一张待标注的图片信息，如果没有则返回null
     */
    @Override
    public PictureInfo saveAnnotationAndGetNext(PictureInfo pictureInfo)
    {
        // 设置更新时间
        pictureInfo.setUpdateTime(new Date());
        // 设置更新用户ID
        pictureInfo.setUpdateUserId(ShiroUtils.getSysUser().getUserId());
        
        // 更新标注信息
        pictureInfoMapper.updatePictureInfo(pictureInfo);
        
        // 从Redis缓存中删除已标注的图片ID
        String redisKey = REDIS_KEY_NEXT_PICTURE + pictureInfo.getId();
        if (redisTemplate.hasKey(redisKey)) {
            redisTemplate.delete(redisKey);
        }
        
        PictureInfo selectNextUnannotatedPicture = null;
        // 获取下一张待标注的图片
        synchronized (this)
        {
            Long picId = null;
            //先获取一张图片
            selectNextUnannotatedPicture = pictureInfoMapper.selectNextUnannotatedPicture(picId);
            while(Objects.nonNull(selectNextUnannotatedPicture)){
                //如果获取到图片记录，则根据图片id，从redis中查询缓存，看有没有人在标注该图片
                Boolean cachedNextPictureId = redisTemplate.hasKey(REDIS_KEY_NEXT_PICTURE + selectNextUnannotatedPicture.getId());
                if(!cachedNextPictureId){
                    // 如果缓存没有该图片的id，说明没有用户在标注，则当前用户占用该图片，3分钟
                    redisTemplate.opsForValue().set(REDIS_KEY_NEXT_PICTURE + selectNextUnannotatedPicture.getId(), selectNextUnannotatedPicture.getId(), 3L, TimeUnit.MINUTES);
                    return selectNextUnannotatedPicture;
                }else{
                    //如果缓存中有该图片ID， 说明有用户在标注该图片，则向后寻找下一张图片
                    picId = selectNextUnannotatedPicture.getId();
                    selectNextUnannotatedPicture = pictureInfoMapper.selectNextUnannotatedPicture(picId);
                }
            }
        }
        return selectNextUnannotatedPicture;
    }

    /**
     * 新增图片信息
     * 
     * @param pictureInfo 图片信息
     * @return 结果
     */
    @Override
    public int insertPictureInfo(PictureInfo pictureInfo)
    {
        return pictureInfoMapper.insertPictureInfo(pictureInfo);
    }

    /**
     * 修改图片信息
     * 
     * @param pictureInfo 图片信息
     * @return 结果
     */
    @Override
    public int updatePictureInfo(PictureInfo pictureInfo)
    {
        return pictureInfoMapper.updatePictureInfo(pictureInfo);
    }

    /**
     * 批量删除图片信息
     * 
     * @param ids 需要删除的图片信息主键集合
     * @return 结果
     */
    @Override
    public int deletePictureInfoByIds(Long[] ids)
    {
        return pictureInfoMapper.deletePictureInfoByIds(ids);
    }

    /**
     * 删除图片信息信息
     * 
     * @param id 图片信息主键
     * @return 结果
     */
    @Override
    public int deletePictureInfoById(Long id)
    {
        return pictureInfoMapper.deletePictureInfoById(id);
    }
}